{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第1关：线性判别分析 - 随机生成数的降维\n",
    "\n",
    "[LDA原理](https://www.educoder.net/tasks/8nqm6yvcbest?subject_id=cuhv94tf)\n",
    "\n",
    "注意，计算协方差矩阵的方法是 `np.cov(X, rowval=False)`，参数`rowval=False`意思是将样本X的每一行看成一个样本，也就是说X.shape=(m,n)，其中m是样本个数，n是特征个数，该矩阵的协方差矩阵的维度是(n,n)。\n",
    "协方差矩阵和散度矩阵 $\\sum_j$ 存在倍数关系，具体可见代码类内散度矩阵计算。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#encoding=utf8 \n",
    "import numpy as np\n",
    "from numpy.linalg import inv\n",
    "def lda(X, y):\n",
    "    '''\n",
    "    input:X(ndarray):待处理数据\n",
    "          y(ndarray):待处理数据标签，标签分别为0和1\n",
    "    output:X_new(ndarray):处理后的数据\n",
    "    '''\n",
    "    #********* Begin *********#\n",
    "    #划分出第一类样本与第二类样本\n",
    "    X0 = X[np.where(y == 0)]\n",
    "    X1 = X[np.where(y == 1)]\n",
    "    #获取第一类样本与第二类样本中心点\n",
    "    u0 = np.mean(X0, axis=0)\n",
    "    u1 = np.mean(X1, axis=0)\n",
    "    #计算第一类样本与第二类样本协方差矩阵\n",
    "    Cov0 = np.cov(X0-u0, rowvar = False)\n",
    "    Cov1 = np.cov(X1-u1, rowvar = False)\n",
    "    #计算类内散度矩阵\n",
    "    Sw = Cov0 * len(X0) + Cov1*len(X1)\n",
    "    #计算w\n",
    "    w = np.dot(np.linalg.inv(Sw), (u0-u1))\n",
    "    #计算新样本集\n",
    "    X_new = np.dot(X, w)\n",
    "    X_new = X_new.reshape([len(X_new), -1])\n",
    "    #********* End *********#\n",
    "    return X_new\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第2关：scikit-learn线性判别实践 - 随机生成的降维"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#encoding=utf8 \n",
    "from sklearn.discriminant_analysis import LinearDiscriminantAnalysis\n",
    "\n",
    "def lda(x,y):\n",
    "    '''\n",
    "    input:x(ndarray):待处理数据\n",
    "          y(ndarray):待处理数据标签\n",
    "    output:x_new(ndarray):降维后数据\n",
    "    '''\n",
    "    #********* Begin *********#\n",
    "    lda = LinearDiscriminantAnalysis(n_components=2)\n",
    "    lda.fit(x,y)\n",
    "    x_new = lda.transform(x)\n",
    "    #********* End *********#\n",
    "    return x_new\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "tf38",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.8.19"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
